<?php

namespace App\Http\Controllers\Home;

use App\Models\DiningReserve;
use App\Models\DiningReserveProd;
use App\Models\ProdOrder;
use App\Models\Product;
use App\Models\RakeBack;
use App\Models\SpreadRecord;
use App\Models\StoreRecord;
use App\Models\Transition;
use App\Models\User;
use App\Models\UserAddress;
use App\Models\UserLevel;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rule;

/**
 * @group 前台接口文档
 * @title 权限模块接口
 * @author chenke
 * @description 酒庄前台权限板块接口
 * @header name:Lang type:string require:1 desc:语言类型(en或zn)
 *  */
class Auth extends Base
{
    /**
     * @title 用户登录
     * @description 用户登录，获取基本信息
     * @url /api/login
     * @method POST
     * @module 注册登录板块
     * @author chenke
     * @param name:email type:string require:1 default: other: desc:用户邮箱（账号）
     * @param name:password type:string require:1 default: other: desc:登录密码
     * @return code:错误码
     * @return message:错误提示
     * @return data: 用户信息@
     * @data id:用户ID email:用户邮箱 username:用户英文名 username_zn:用户中文名 contact:联系电话 total:累计消费总额 birthday:用户生日 spread:推荐人推广ID
     */
    public function userLogin(Request $request){
        $lang  = $request->header('Lang')?$request->header('Lang'):'zn';
        $data = $request->post();
        $rules = [
            'email'=>'required|email',
            'password'=>'required|string'
        ];
        $messages = [
            'email.required'=> $this->lang['REQUIRED'][$lang],
            'email.email'=> $this->lang['EMAIL'][$lang],
            'password.required'=> $this->lang['REQUIRED'][$lang]
        ];
        $check = $this->checkParams($data,$rules,$messages);
        if($check['code']){
            return response()->json($check);
        }
        $result = (new User())->login($data,$lang);
        if($result['code']){
            $this->logErr($result['code'],$result['message'],'userLogin');
        }
        return response()->json($result);
    }

    /**
     * @title 获取用户信息
     * @description 登录后，获取用户基本信息
     * @url /api/auth/userinfo
     * @method GET
     * @module 用户信息板块
     * @author chenke
     * @header name:Token type:string require:1 desc:登录令牌
     * @return code:错误码
     * @return message:错误提示
     * @return data: 等级信息@
     * @data levelid:用户等级ID avator:用户头像 email:用户邮箱 username:用户英文名 paypass:是否设置交易密码 username_zn:用户中文名 balance:钱包余额 created_at:注册时间 cycle_balance:反馈钱包余额 coin:可用积分 contact:联系电话 total:累计消费总额 birthday:用户生日
     */
    public function userInfo(Request $request){
        try {
            $user = (new User())->where('token',$request->token)
                      ->select('id','spreadid','email','avator','username','paypass','username_zn','contact','balance','cycle_balance','coin','total','birthday','created_at')
                      ->first();
            $userlevel = (new UserLevel())->where([
                ['min','<=',$user->total], ['max','>',$user->total]
            ])->value('id');
            $user = $user->toArray();
            $user['levelid'] = $userlevel;
            $user['paypass'] =  $user['paypass']?true:false;
            unset($user['id']);
            if($user){
                return response()->json([
                    'code'=>0,
                    'data'=>$user
                ]);
            }else{
                return response()->json([
                    'code'=>1,
                    'message'=>$this->lang['GET_FAIL'][$request->lang]
                ]);
            }
        }catch (\Exception $e){
            $this->logErr($e->getCode(),$e->getMessage(),'userInfo');
            return response()->json( [
                'code'=>1,
                'message'=>$this->lang['ERROR'][$request->lang]
            ]);
        }
    }

    /**
     * @title 个人资料编辑
     * @description 登录后，个人资料编辑
     * @url /api/auth/setinfo
     * @method POST
     * @module 用户信息板块
     * @author chenke
     * @header name:Token type:string require:1 desc:登录令牌
     * @param name:avator type:string require:1 default: other: desc:头像
     * @param name:username type:string require:1 default: other: desc:英文名
     * @param name:username_zn type:string require:1 default: other: desc:中文名
     * @param name:contact type:string require:1 default: other: desc:联系方式
     * @param name:birthday type:string require:0 default: other: desc:生日
     * @return code:错误码
     * @return message:错误提示
     * @return data:成功时返回空
     */
    public function userInfoSet(Request $request){
        try {
            $data = $request->post();
            $rules = [
                'avator'=>'required|string',
                'username'=>'required|string',
                'username_zn'=>'required|string',
                'contact'=>'required|string',
                'birthday'=>'date',
            ];
            $messages = [
                'avator.required'=> $this->lang['REQUIRED'][$request->lang],
                'username.required'=> $this->lang['REQUIRED'][$request->lang],
                'username_zn.required'=> $this->lang['REQUIRED'][$request->lang],
                'contact.required'=> $this->lang['REQUIRED'][$request->lang],
                'birthday.date'=> $this->lang['DATE'][$request->lang]
            ];
            $check = $this->checkParams($data,$rules,$messages);
            if($check['code']){
                return response()->json($check);
            }
            $user = (new User())->where('token',$request->token)->first();
            if(!$user){
                return response()->json([
                    'code'=>50000,
                    'message'=>$this->lang['LOGIN_EXPIRE'][$request->lang]
                ]);
            }
            if($user->deleted_at){
                return response()->json([
                    'code'=>1,
                    'message'=>$this->lang['USER_FORBIDDEN'][$request->lang]
                ]);
            }
            $user->avator = $data['avator'];
            $user->username = $data['username'];
            $user->username_zn = $data['username_zn'];
            $user->contact = $data['contact'];
            if(isset($data['birthday']) && $data['birthday']){
                $user->birthday = $data['birthday'];
            }
            $user->save();
            return response()->json([
                'code'=>0,
                'data'=>''
            ]);
        }catch (\Exception $e){
            $this->logErr($e->getCode(),$e->getMessage(),'storeList');
            return response()->json( [
                'code'=>1,
                'message'=>$this->lang['ERROR'][$request->lang]
            ]);
        }
    }

    /**
     * @title 获取所有用户等级
     * @description 登录后，获取所有用户等级
     * @url /api/auth/ulevels
     * @method GET
     * @module 用户信息板块
     * @author chenke
     * @header name:Token type:string require:1 desc:登录令牌
     * @return code:错误码
     * @return message:错误提示
     * @return data: 用户信息@
     * @data id:用户等级ID levelname:等级英文名 levelname_zn:等级中文名 min:最低消费 max:最高消费 cycle_rate:反馈比例 integral:积分反馈比例
     */
    public function userLevels(Request $request){
        try {
            $levels = UserLevel::all();
            if($levels){
                return response()->json([
                    'code'=>0,
                    'data'=>$levels->toArray()
                ]);
            }else{
                return response()->json([
                    'code'=>1,
                    'message'=>$this->lang['GET_FAIL'][$request->lang]
                ]);
            }
        }catch (\Exception $e){
            $this->logErr($e->getCode(),$e->getMessage(),'userLevels');
            return response()->json( [
                'code'=>1,
                'message'=>$this->lang['ERROR'][$request->lang]
            ]);
        }
    }

    /**
     * @title 获取用户常消费记录
     * @description 登录后，获取用户常消费记录
     * @url /api/auth/consumes
     * @method GET
     * @module 用户信息板块
     * @author chenke
     * @header name:Token type:string require:1 desc:登录令牌
     * @return code:错误码
     * @return message:错误提示
     * @return data: 消费信息@
     * @data name:商品名称 number:商品数量 date:消费日期
     */
    public function consumption(Request $request){
        try {
            $user = (new User())->where('token',$request->token)->select('id','deleted_at')->first();
            if(!$user){
                return response()->json([
                    'code'=>50000,
                    'message'=>$this->lang['LOGIN_EXPIRE'][$request->lang]
                ]);
            }
            if($user->deleted_at){
                return response()->json([
                    'code'=>1,
                    'message'=>$this->lang['USER_FORBIDDEN'][$request->lang]
                ]);
            }
            $Prods = [];
            $date = date('Y-m-d',time()-3600*24*90);
            $orderProds = (new ProdOrder())->where('uid',$user->id)->whereIn('status',[2,3,4])->whereDate('updated_at','>',$date)
                        ->selectRaw('proid,sum(pronum) as number')->groupBy('proid')->orderByRaw('number desc')->get();
            if(!empty($orderProds)){
                foreach ($orderProds as $prod){
                    $Prods[intval($prod->proid)] = intval($prod->number);
                }
            }
            $dids = (new DiningReserve())->where('uid',$user->id)->whereIn('status',[1,2,3,4])->whereDate('updated_at','>',$date)->pluck('id');
            if(!empty($dids)){
                $diniProds = (new DiningReserveProd())->whereIn('did',$dids)->groupBy('proid')->selectRaw('proid,sum(pronum) as number')
                            ->orderByRaw('number desc')->get();
                foreach ($diniProds as $prod){
                    if(isset($Prods[$prod->proid])){
                        $Prods[intval($prod->proid)] += intval($prod->number);
                    }else{
                        $Prods[intval($prod->proid)] = intval($prod->number);
                    }
                }
            }
            arsort($Prods,SORT_NUMERIC );
            $arr = array_slice($Prods, 0, 5, true);
            $return = [];
            foreach ($arr as $key=>$v){
                $proinfo = (new Product())->where('id',$key)->select('id','proname','proname_zn')->first();
                $return[$key] = $proinfo->toArray();
                $return[$key]['number'] = $v;
            }
            return response()->json( [
                'code'=>0,
                'data'=>$return
            ]);
        }catch (\Exception $e){
            $this->logErr($e->getCode(),$e->getMessage(),'userLevels');
            return response()->json( [
                'code'=>1,
                'message'=>$e->getMessage()//$this->lang['ERROR'][$request->lang]
            ]);
        }
    }

    /**
     * @title 获取用户所有收货地址
     * @description 登录后，获取用户所有收货地址
     * @url /api/auth/uaddress
     * @method GET
     * @module 用户信息板块
     * @author chenke
     * @header name:Token type:string require:1 desc:登录令牌
     * @return code:错误码
     * @return message:错误提示
     * @return data: 地址信息@
     * @data id:地址ID username:收货人姓名 contact:收货人电话 address:详细地址 isdefault:是否默认地址(1为默认)
     */
    public function userAddresses(Request $request){
        try {
            $uid = (new User())->where('token',$request->token)->value('id');
            $address= UserAddress::where('uid',$uid)->get();
            if($address){
                return response()->json([
                    'code'=>0,
                    'data'=>$address->toArray()
                ]);
            }else{
                return response()->json([
                    'code'=>1,
                    'message'=>$this->lang['GET_FAIL'][$request->lang]
                ]);
            }
        }catch (\Exception $e){
            $this->logErr($e->getCode(),$e->getMessage(),'userAddresses');
            return response()->json( [
                'code'=>1,
                'message'=>$this->lang['ERROR'][$request->lang]
            ]);
        }
    }

    /**
     * @title 获取用户推荐人信息
     * @description 登录后，获取用户推荐人信息
     * @url /api/auth/spredinfo
     * @method GET
     * @module 用户信息板块
     * @author chenke
     * @header name:Token type:string require:1 desc:登录令牌
     * @return code:错误码
     * @return message:错误提示
     * @return data: 推荐人信息@
     * @data id:推荐ID spreadid:推广用户的推荐号 email:用户邮箱 username:用户英文名 username_zn:用户中文名 created_at:推广时间 contact:联系电话
     */
    public function spreadInfo(Request $request){
        try {
            $uid = (new User())->where('token',$request->token)->value('id');
            $record = (new SpreadRecord())->where('uid','=',$uid)->first();
            if($record){
                $user = (new User())->where('spreadid',$record->spreadid)->select('id','username','username_zn','contact','email')->first();
                $data = $record->toArray();
                $data['spreadid'] = $record->spreadid;
                $data['username'] = $user->username;
                $data['username_zn'] = $user->username_zn;
                $data['contact'] = $user->contact;
                $data['email'] = $user->email;
                return response()->json([
                    'code'=>0,
                    'data'=>$data
                ]);
            }else{
                return response()->json([
                    'code'=>0,
                    'data'=>[]
                ]);
            }
        }catch (\Exception $e){
            $this->logErr($e->getCode(),$e->getMessage(),'spreadInfo');
            return response()->json( [
                'code'=>1,
                'message'=>$this->lang['ERROR'][$request->lang]
            ]);
        }
    }

    /**
     * @title 获取用户存酒记录
     * @description 登录后，获取用户存酒记录
     * @url /api/auth/stores
     * @method GET
     * @module 用户信息板块
     * @author chenke
     * @header name:Token type:string require:1 desc:登录令牌
     * @return code:错误码
     * @return message:错误提示
     * @return data: 存储信息@
     * @data id:记录ID proid:商品ID number:存储数量 proname:商品英文名 proname_zn:商品中文名 rprice:商品活动价 image:商品主图 created_at:存储时间
     */
    public function storeList(Request $request){
        try {
            $uid = (new User())->where('token',$request->token)->value('id');
            $stores = (new StoreRecord())->join('products','products.id','=','store_records.proid')
                      ->select('store_records.*','products.rprice','products.image','products.proname','products.proname_zn')
                     ->where('uid',$uid)->get();
            if($stores){
                return response()->json([
                    'code'=>0,
                    'data'=>$stores->toArray()
                ]);
            }else{
                return response()->json([
                    'code'=>0,
                    'data'=>[]
                ]);
            }
        }catch (\Exception $e){
            $this->logErr($e->getCode(),$e->getMessage(),'storeList');
            return response()->json( [
                'code'=>1,
                'message'=>$this->lang['ERROR'][$request->lang]
            ]);
        }
    }

    /**
     * @title 获取用户推荐直属信息
     * @description 登录后，获取用户推荐直属信息
     * @url /api/auth/spreds
     * @method GET
     * @module 用户信息板块
     * @author chenke
     * @header name:Token type:string require:1 desc:登录令牌
     * @return code:错误码
     * @return message:错误提示
     * @return data: 推荐信息@
     * @data subs:推广人列表数据@ total:返佣总金额 count:推广总人数 new:今日新增人数
     * @subs username:用户英文名 username_zn:用户中文名 avator:用户头像 total:订单总金额 number:所得佣金 created_at:所得时间 status:佣金状态(1到账2退款)
     */
    public function spreadList(Request $request){
        try {
            $user = (new User())->where('token',$request->token)->select('id','spreadid')->first();
            $subordinates = (new SpreadRecord())->join('users','users.id','=','spread_records.uid')
                ->select('spread_records.*','users.avator','users.username','users.username_zn')
                ->where('spread_records.spreadid',$user->spreadid)->get()->toArray();
            $total = 0;
            if(!empty($subordinates)){
                $count = count($subordinates);
                $new = (new SpreadRecord())->where('spreadid',$user->spreadid)->whereDate('created_at','=',date('Y-m-d'))->count();
                foreach ($subordinates as &$sub){
                    $trans = (new RakeBack())->where([
                        ['uid','=',$sub['uid']],['status','=',1],['spreadid','=',$user->spreadid],['created_at','>',$sub['created_at']]
                    ])->first();
                    if($trans){
                        $sub['total'] = $trans->total;
                        $sub['number'] = $trans->number;
                        $total += $trans->number;
                    }
                }
                return response()->json([
                    'code'=>0,
                    'data'=>[
                        'subs'=>$subordinates,
                        'total'=>$total,
                        'count'=>$count,
                        'new'=>$new
                    ]
                ]);
            }else{
                return response()->json([
                    'code'=>0,
                    'data'=>[
                        'subs'=>[],
                        'total'=>0,
                        'count'=>0,
                        'new'=>0
                    ]
                ]);
            }
        }catch (\Exception $e){
            $this->logErr($e->getCode(),$e->getMessage(),'storeList');
            return response()->json( [
                'code'=>1,
                'message'=>$this->lang['ERROR'][$request->lang]
            ]);
        }
    }

    /**
     * @title 推荐人绑定
     * @description 登录后，绑定推荐人
     * @url /api/auth/bdspred
     * @method POST
     * @module 用户信息板块
     * @author chenke
     * @header name:Token type:string require:1 desc:登录令牌
     * @param name:spreadid type:string require:1 default: other: desc:推荐人推广ID
     * @return code:错误码
     * @return message:错误提示
     * @return data:成功时返回空
     */
    public function bindSpread(Request $request){
        try {
            $data = $request->post();
            $rules = [
                'spreadid'=>'required|string'
            ];
            $messages = [
                'spreadid.required'=> $this->lang['REQUIRED'][$request->lang],
                'spreadid.string'=>  $this->lang['STRING'][$request->lang]
            ];
            $check = $this->checkParams($data,$rules,$messages);
            if($check['code']){
                return response()->json($check);
            }
            $data['token'] = $request->token;
            $result =  (new SpreadRecord())->bindAdd($data,$request->lang);
            if($result['code']){
                $this->logErr($result['code'],$result['message'],'toTrans');
            }
            return response()->json($result);
        }catch (\Exception $e){
            $this->logErr($e->getCode(),$e->getMessage(),'storeList');
            return response()->json( [
                'code'=>1,
                'message'=>$this->lang['ERROR'][$request->lang]
            ]);
        }
    }

    /**
     * @title 设置交易密码
     * @description 登录后，交易密码设置
     * @url /api/auth/payset
     * @method POST
     * @module 用户信息板块
     * @author chenke
     * @header name:Token type:string require:1 desc:登录令牌
     * @param name:pass type:string require:1 default: other: desc:登录密码
     * @param name:paypass type:int require:1 default: other: desc:交易密码
     * @param name:paypass_confirmation type:int require:1 default: other: desc:交易密码确认
     * @return code:错误码
     * @return message:错误提示
     * @return data:成功时返回空
     */
    public function payPassSet(Request $request){
        try {
            $data = $request->post();
            $rules = [
                'pass'=>'required|string',
                'paypass'=>[
                    'required','confirmed','integer','regex:/^\d{6}$/'
                ],
                'paypass_confirmation'=>'required|same:paypass'
            ];
            $messages = [
                'pass.required'=> $this->lang['REQUIRED'][$request->lang],
                'paypass.confirmed'=> $this->lang['CONFIRM'][$request->lang],
                'paypass.regex'=> $this->lang['REGEX'][$request->lang],
                'paypass.integer'=> $this->lang['INTEGER'][$request->lang],
                'paypass_confirmation.required'=> $this->lang['REQUIRED'][$request->lang],
                'password_confirmation.same'=> $this->lang['CONFIRM'][$request->lang]
            ];
            $check = $this->checkParams($data,$rules,$messages);
            if($check['code']){
                return response()->json($check);
            }
            $user = (new User())->where('token',$request->token)->first();
            if(!$user){
                return response()->json([
                    'code'=>50000,
                    'message'=>$this->lang['LOGIN_EXPIRE'][$request->lang]
                ]);
            }
            if($user->deleted_at){
                return response()->json([
                    'code'=>1,
                    'message'=>$this->lang['USER_FORBIDDEN'][$request->lang]
                ]);
            }
            if(!Hash::check($data['pass'],$user->password)){
                return response()->json([
                    'code'=>1,
                    'message'=>$this->lang['PASS_ERROR'][$request->lang]
                ]);
            }
            $user->paypass = Hash::make($data['paypass']);
            $user->save();
            return response()->json([
                'code'=>0,
                'data'=>''
            ]);
        }catch (\Exception $e){
            $this->logErr($e->getCode(),$e->getMessage(),'storeList');
            return response()->json( [
                'code'=>1,
                'message'=>$this->lang['ERROR'][$request->lang]
            ]);
        }
    }

    /**
     * @title 设置登录密码
     * @description 登录后，登录密码设置
     * @url /api/auth/passset
     * @method POST
     * @module 用户信息板块
     * @author chenke
     * @header name:Token type:string require:1 desc:登录令牌
     * @param name:oldpass type:string require:1 default: other: desc:原登录密码
     * @param name:password type:string require:1 default: other: desc:新登录密码
     * @param name:password_confirmation type:string require:1 default: other: desc:新登录密码确认
     * @return code:错误码
     * @return message:错误提示
     * @return data:成功时返回空
     */
    public function passWordSet(Request $request){
        try {
            $data = $request->post();
            $rules = [
                'oldpass'=>'required|string',
                'password'=>[
                    'required','confirmed','regex:/\w{6,20}/i'
                ],
                'password_confirmation'=>'required|same:password'
            ];
            $messages = [
                'oldpass.required'=> $this->lang['REQUIRED'][$request->lang],
                'password.confirmed'=> $this->lang['CONFIRM'][$request->lang],
                'password.regex'=> $this->lang['REGEX'][$request->lang],
                'password_confirmation.required'=> $this->lang['REQUIRED'][$request->lang],
                'password_confirmation.same'=> $this->lang['CONFIRM'][$request->lang]
            ];
            $check = $this->checkParams($data,$rules,$messages);
            if($check['code']){
                return response()->json($check);
            }
            $user = (new User())->where('token',$request->token)->first();
            if(!$user){
                return response()->json([
                    'code'=>50000,
                    'message'=>$this->lang['LOGIN_EXPIRE'][$request->lang]
                ]);
            }
            if($user->deleted_at){
                return response()->json([
                    'code'=>1,
                    'message'=>$this->lang['USER_FORBIDDEN'][$request->lang]
                ]);
            }
            if(!Hash::check($data['oldpass'],$user->password)){
                return response()->json([
                    'code'=>1,
                    'message'=>$this->lang['PASS_ERROR'][$request->lang]
                ]);
            }
            $user->password = Hash::make($data['password']);
            $user->save();
            return response()->json([
                'code'=>0,
                'data'=>''
            ]);
        }catch (\Exception $e){
            $this->logErr($e->getCode(),$e->getMessage(),'storeList');
            return response()->json( [
                'code'=>1,
                'message'=>$this->lang['ERROR'][$request->lang]
            ]);
        }
    }
}
